//
// Created by ttao on 2022/8/4.
//

#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include "hash/container.h"
#define ISNULL(node) (!node || node == NULL)
#define ISNOTNULL(node) (!ISNULL(node))
/* ================ start of Stack.c ================ */
/*
 * eg:  初始化栈
        stack s;
        char *c[100];
        initStack(&s, c, sizeof(c)/sizeof(char *));
 */
//清空栈
void stack_clear(stack *s)
{
    while(s->point!=0)
    {
        s->head[s->point-1] = NULL;
        s->point--;
    }
}
//堆栈是否为空
int isempty(stack *s)
{
    return(s->point == 0);
}
//入栈函数
int push(stack *s, void *node)
{
    if(s->point < s->maxlen)
    {
        s->head[(s->point)++] = node;
        return(0);
    }
    else
        return(-1);
}
//出栈函数
void *pop(stack *s)
{
    if(s->point >0)
        return(s->head[--(s->point)]);
    else
        return(0);
}
/* ================ end of Stack.c ================ */

/* ================ start of Queue.c ================ */
/*
 *  eg: 队列
    struct Queue queue;
    initQueue(&queue, 100);

    add(queue, dtsnew("hello"));
    dts dts1 = (dts)get(&queue);
 */
struct Queue *initQueue(struct Queue *queue, int MAXSIZE)
        /*初始化队列*/
{
    queue->maxsize = MAXSIZE;
    queue->size = 0;
    queue->head = NULL;
    queue->tail = NULL;
    return queue;
}
struct Queue *add(struct Queue *queue, void *val)
        /*数据入队列*/
{
    struct Table * table = (struct Table *)malloc(sizeof(struct Table));
    table->value = val;
    table->next = NULL;
    if(queue->head == NULL && queue->tail == NULL)
    {
        table->prev = NULL;
        queue->head = table;
        queue->tail = table;
    } else {
        table->prev = queue->tail;
        queue->tail->next = table;
        queue->tail = table;
    }
    queue->size++;
    return queue;
}

void *get(struct Queue *queue)
        /*数据出队列*/
{
    if(ISNULL(queue->head) && ISNULL(queue->tail))
        return NULL;
    struct Table *table = queue->head;
    if(!ISNULL(queue->head) && !ISNULL(queue->tail) && (queue->head == queue->tail))
    {
        queue->size = 0;
        queue->head = NULL;
        queue->tail = NULL;
    }else{
        queue->head = table->next;
        queue->size--;
    }
    return table->value;
}
void queueeach(struct Queue *queue, void (*queueeachcallbak)(void *val))
// 回调查询
{
    for(void * val = get(queue);val != NULL; val = get(queue))
        queueeachcallbak(val);
}
/* ================ end of Queue.c ================ */


/* ================ end of Lists.c ================ */
void initLinkList(linklist_t *list)                 // 初始化链表
{
    list->size = 0;
    list->head = NULL;
    list->tail = NULL;
}
static inline void insertnode(linklist_t *list, table_t *tb, table_t *itb, enum InsertType type)  // 插入元素
{
    list->size++;
    if(ISNULL(list->head) && ISNULL(list->tail) && ISNULL(itb)) // 首次插入
    {
        list->head = list->tail = tb;
        return;
    }
    switch (type) {
        case BEFORE:
            tb->next = itb;
            tb->prev = itb->prev;
            if(ISNULL(itb->prev))
                list->head = tb;
            itb->prev = tb;
            break;
        case AFTER:
            tb->next = itb->next;
            tb->prev = itb;
            if(ISNULL(itb->next))
                list->tail = tb;
            itb->next = tb;
            break;
    }
}
void inserttable(linklist_t *list, void *val, table_t *itb, enum InsertType type)
{
    if(ISNULL(itb) || ISNULL(list)) return;
    table_t *tb = (table_t *) malloc(sizeof(table_t));
    tb->value = val;
    tb->next = NULL;
    tb->prev = NULL;
    if(ISNOTNULL(tb))
        insertnode(list, tb, itb, type);
}
void addlinklisttable(linklist_t *list, void *val)          // 追加数据 后面插入
{
    if(ISNULL(list)) return;
    table_t *tb = (table_t *) malloc(sizeof(table_t));
    tb->value = val;
    tb->next = NULL;
    tb->prev = NULL;
    if(ISNOTNULL(tb))
        insertnode(list, tb, list->tail, AFTER);
}
void selmetatable(linklist_t *list)
{
    list->cursor = list->head;
}
int hasnext(linklist_t *list){
    if(ISNULL(list->cursor))
        return 0;
}
table_t *getTb(linklist_t *list)
{
    table_t * t = list->cursor;
    if(ISNOTNULL(t))
        list->cursor = list->cursor->next;
    return t;
}
void linklisteachinit(linklist_t *list)// 元素遍历
{
    selmetatable(list);
}
int destrylinklist(linklist_t *list, table_t *tb)                    // 销毁元素
{
    if(ISNOTNULL(tb->prev) && ISNOTNULL(tb->next))
    {
        tb->prev->next = tb->next;
        tb->next->prev = tb->prev;
    }
    if(ISNULL(tb->prev))
    {
        list->head = tb->next;
        if(ISNOTNULL(list->head))
            list->head->prev = NULL;
    }
    if(ISNULL(tb->next))
    {
        list->tail = tb->prev;
        if(ISNOTNULL(list->tail))
            list->tail->next = NULL;
    }
    list->size--;
    free(tb);
}
/* ================ start of Lists.c ================ */
